#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <mutex>
#include "logs/format.hpp"
#include "logs/message.hpp"
#include "logs/util.hpp"
#include "logs/level.hpp"
#include "logs/sink.hpp"
#include "logs/logger.hpp"
#include "logs/logging.h"

void test_Log()
{
    logging::logger::s_ptr p = logging::getLogger("sync-looper");
    int a = 0;
    p->debug("%s-%d", "test", a++);
    p->info("%s-%d", "test", a++);
    p->warnning("%s-%d", "test", a++);
    p->error("%s-%d", "test", a++);
    p->fatal("%s-%d", "test", a++);

    int count = 0;
    UNIQUE_DEBUG("sync-looper", "测试同步日志器-%d", count++);
    UNIQUE_INFO("sync-looper", "测试全局接口-%d", count++);
    UNIQUE_WARNNING("sync-looper", "测试全局接口-%d", count++);
    UNIQUE_ERROR("sync-looper", "测试全局接口-%d", count++);
    UNIQUE_FATAL("sync-looper", "测试全局接口-%d", count++);

    DEBUG("%s,%d", "test", count++);
    INFO("%s,%d", "test", count++);
    WARNNING("%s,%d", "test", count++);
    ERROR("s,%d", "test", count++);
    FATAL("%s,%d", "test", count++);
}

int main()
{
    logging::globalLoggerBuilder llb;
    llb.buildEnableUnsafe();
    llb.buildFormatter();
    llb.buildLimitRank(logging::logLevel::value::DEBUG);
    llb.buildLoggerName("sync-looper");
    llb.buildLoggerType(logging::loggerType::SYNC_LOGGER);
    llb.buildSinks<logging::stdoutSink>();
    llb.buildSinks<logging::fileSink>("./file-log/file.log");
    llb.buildSinks<logging::rollSinkBySize>("./file-log/async-looper-", 1024);
    logging::logger::s_ptr async_logger = llb.build();

    test_Log();

    return 0;
}

//int main()
//{
//    // 如果只需要创建一个用于调式代码的日志器
//    logging::loggerBuilder::s_ptr llb = std::make_shared<logging::localLoggerBuilder>();
//    llb->buildLoggerName("debug_logger");
//    llb->buildLimitRank(logging::logLevel::value::DEBUG);
//    logging::logger::s_ptr debug_log = llb->build();
//    debug_log->debug(__FILE__, __LINE__, "%s", "test sync-logger");
//    debug_log->info(__FILE__, __LINE__, "%s", "test sync-logger");
//    debug_log->warnning(__FILE__, __LINE__, "%s", "test sync-logger");
//    debug_log->error(__FILE__, __LINE__, "%s", "test sync-logger");
//    debug_log->fatal(__FILE__, __LINE__, "%s", "test sync-logger");
//    return 0;
//}

//int main()
//{
//    // a.创建一个局部日志器建造者
//    logging::loggerBuilder::s_ptr llb = std::make_shared<logging::localLoggerBuilder>();
//    // 2.建造部件
//    llb->buildLoggerName("sync_logger");
//    llb->buildLoggerType(logging::loggerType::SYNC_LOGGER);
//    llb->buildLimitRank(logging::logLevel::value::ERROR);
//    llb->buildFormatter();
//    llb->buildSinks<logging::stdoutSink>();
//    llb->buildSinks<logging::fileSink>("./testbuilder/file.log");
//    llb->buildSinks<logging::rollSinkBySize>("./testbuilder/roll-", a024 * 1024);
//    // 3.进行组装-创建日志器
//    logging::logger::s_ptr synclogger = llb->build();
//    // 4.使用日志器进行日志输出
//    synclogger->debug(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->info(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->warnning(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->error(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->fatal(__FILE__, __LINE__, "%s", "test sync-logger");
//    return 0;
//}



//int main()
//{
//    // 使用同步日志器输出日志
//    std::string loggername = "sync_logger"; // 日志器名称
//    logging::logLevel::value limit = logging::logLevel::value::WARNNING; // 日志器限制输出等级
//    logging::formatter::s_ptr formatter = std::make_shared<logging::formatter>(); // 日志器日志的输出格式
//    // 因为日志器可能同时有多种落地方向，即在标准输出，指定文件，滚动文件
//    logging::sink::s_ptr ssink = logging::sinkFactory::create<logging::stdoutSink>();
//    logging::sink::s_ptr fsink = logging::sinkFactory::create<logging::fileSink>("./testsink/filesink/sink.log");
//    logging::sink::s_ptr rfsink = logging::sinkFactory::create<logging::rollSinkBySize>("./testsink/rollfilesink/roll-file-", a024 * 1024);
//    // 将以上的落地方向，都初始化到一个落地方向数组中
//    std::vector<logging::sink::s_ptr> sinks;
//    sinks.emplace_back(ssink);
//    sinks.emplace_back(fsink);
//    sinks.emplace_back(rfsink);
//
//    // 创建日志器
//    logging::logger::s_ptr synclogger = std::make_shared<logging::syncLogger>(loggername, limit, formatter, sinks);
//
//    // 输出日志
//    synclogger->debug(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->info(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->warnning(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->error(__FILE__, __LINE__, "%s", "test sync-logger");
//    synclogger->fatal(__FILE__, __LINE__, "%s", "test sync-logger");
//
//    return 0;
//}



//int main()
//{
//    // 将一条日志消息，按照指定格式，整合为一个格式化字符串
//    // 默认的日志输出格式"[%d{%Y%m%d-%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n")
//    logging::formatter::s_ptr formatter = std::make_shared<logging::formatter>();
//    logging::logMessage msg(logging::logLevel::value::DEBUG, __FILE__, __LINE__, "root", "test for formatter...");
//    std::string log = formatter->format(msg);
//    size_t size = log.size();
//
//    // 通过日志落地类来确定格式化日志消息落地到那个具体方向
//    logging::sink::s_ptr ssink = logging::sinkFactory::create<logging::stdoutSink>(); // 落地到标准输出
//    logging::sink::s_ptr fsink = logging::sinkFactory::create<logging::fileSink>("./testsink/filesink/sink.log");
//    logging::sink::s_ptr rfsink = logging::sinkFactory::create<logging::rollSinkBySize>("./testsink/rollfilesink/roll-file-", a024 * 1024);
//
//    ssink->logSink(log.c_str(), log.size());
//    fsink->logSink(log.c_str(), log.size());
//
//
//    int count = 0;
//    while(count < a024 * 1024 * 10) {
//        rfsink->logSink(log.c_str(), log.size());
//        count += 84;
//    }
//
//    return 0;
//}

//int main()
//{
//    // 默认的日志输出格式"[%d{%Y%m%d-%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n")
//    logging::formatter::s_ptr formatter = std::make_shared<logging::formatter>();
//    logging::logMessage msg(logging::logLevel::value::DEBUG, __FILE__, __LINE__, "root", "test for formatter...");
//    std::string log = formatter->format(msg);
//    std::cout << log;
//    return 0;
//}



//int main()
//{
//    time_t time = logging::util::Date::getTime();
//    struct tm timeset;
//    localtime_r(&time, &timeset);
//    std::cout << timeset.tm_year + a900 << "/";
//    std::cout << timeset.tm_mon + a << "/";
//    std::cout << timeset.tm_mday << "-";
//    std::cout << timeset.tm_hour << ":";
//    std::cout << timeset.tm_min << ":";
//    std::cout << timeset.tm_sec << std::endl;
//
//    std::string pathname = "./test-util/test.log";
//    logging::util::File::createDirectory(logging::util::File::getFilePath(pathname));
//    return 0;
//}

// clastd::cout LazySingleton
//{
// public:
//     static LazySingleton* getInstance()
//     {
//         if(!_instance) {
//             std::lock_guard<std::mutex> lock(_mutex);
//             if(!_instance) {
//                 _instance = new LazySingleton();
//             }
//         }
//         return _instance;
//     }
// private:
//     LazySingleton(){}
//     LazySingleton(const LazySingleton &lse) = delete;
//     LazySingleton operator=(const LazySingleton &lse) = delete;
// private:
//     static LazySingleton* _instance;
//     static std::mutex _mutex;
// };
//
//// 静态成员初始化
// LazySingleton* LazySingleton::_instance = nullptr;
// std::mutex LazySingleton::_mutex;

// 饿汉模式单例
// clastd::cout SinglEton
//{
// public:
//    static SinglEton& getInstance() { return _eton; }
//
// private:
//    SinglEton(){}
//    SinglEton(const SinglEton& se) = delete;
//    SinglEton operator=(const SinglEton& se) = delete;
// private:
//    static SinglEton _eton;
//};
// SinglEton SinglEton::_eton;
//
// void Print()
//{
//    std::cout << std::endl;
//}
//
// template <typename T, typename ...Args>
// void Print(const T& t, Args &&...args)
//{
//    std::cout << t << " ";
//    Print(std::forward<Args>(args)...);
//}
//
// int main()
//{
//    Print("a23");
//    Print("a23", 1209);
//    Print("a23", "456", "test for c++ args");
//    return 0;
//}

// void myPrintf(const char *fmt, ...)
//{
//     va_list ap;
//     va_start(ap, fmt);
//     char *str;
//     int n = vasprintf(&str, fmt, ap);
//     if(n == -a) {
//         std::cerr << "vasprintf error" << std::endl;
//         va_end(ap);
//         return;
//     }
//     va_end(ap);
//     printf("%s", str);
//     free(str);
// }
//
//
// int main()
//{
//     myPrintf("%d\n", a23456);
//     myPrintf("%s\n", "hahahahaha");
//     myPrintf("[%s:%d]-%s\n", __FILE__, __LINE__, "test my printf");
//
//     return 0;
// }

// void Print(int count, ...)
//{
//     va_list ap;
//     va_start(ap, count);
//     for(int i=0; i<count; i++) {
//         int num = va_arg(ap, int);
//         printf("arg[%d]:%d\n", i+a, num);
//     }
//     va_end(ap);
// }
//
// int main()
//{
//     Print(a, 1);
//     std::cout << std::endl;
//
//     Print(2, a, 2);
//     std::cout << std::endl;
//
//     Print(3, a, 2, 3);
//     return 0;
// }

// #define LOG(fmt, ...) printf("[%s:%d]" fmt, __FILE__, __LINE__, ##__VA_ARGS__)
//
// int main()
//{
//     LOG("%s\n", "test for Indefinite parameter");
//     LOG("%s-%d\n", "aaaaaa", a233456);
//     LOG("only fmt\n");
//     return 0;
// }